﻿#region File Header
//-----------------------------------------------------------------------------
// Bricks' Bane
//
// Copyright (C) 2010 Julien Villers
// This program is distributed under the terms of the 
// GNU Lesser General Public License (LGPL).
// See Docs/lgpl.txt and Docs/gpl.txt
//-----------------------------------------------------------------------------
#endregion

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using SibLib.Entities;
using SibLib.Render;
using SibLib.Render.Primitives3D;

namespace BricksBane.Entities
{
    sealed class Drop : GameplayObject, ICollideable2D
    {
        Rectangle m_BoundingBox;

        public enum E_DropTypes
        {
            // Pad size [stack]
            Extension = 0,
            Reduction,
            // Pad type [replace]
            Standard,
            Laser,
            Magnet,
            Glue,
            Pauser,
            // Ball types
            Baseball,
            Superball,
            Perforaball,
            Nitroball,
            // Speed [stack]
            SpeedUp,
            SpeedDown,
            // Ball count
            BallDouble,
            BallTriple,
            BallQuintuple,
            // Shields
            PadShieldTime,
            PadShieldHit,
            LevelShieldTime,
            LevelShieldHit,
            
            // Count
            Count_
        };

        #region Colors
        private static readonly Color[] COLORS =
        {
            // Size
            Color.Blue,
            Color.Red,
            // Paddles
            Color.Gray,
            Color.Red,
            Color.Blue,
            Color.Green,
            Color.Black,
            // Balls
            Color.Gray,
            Color.Purple,
            Color.Yellow,
            Color.Red,
            // Speed
            Color.Yellow,
            Color.Green,
            // Count
            Color.Blue,
            Color.Blue,
            Color.Blue,
            // Shields
            Color.LimeGreen,
            Color.Lime,
            Color.LimeGreen,
            Color.Lime,
        };
        #endregion

        #region Letters
        private static readonly string[] LETTERS =
        {
            // Size
            "E",
            "R",
            // Paddles
            "SP",
            "L",
            "M",
            "G",
            "P",
            // Balls
            "SB",
            "H",
            "P",
            "C",
            // Speed
            "F",
            "S",
            // Count
            "D",
            "T",
            "Q",
            // Shields
            "PS",
            "PS",
            "N",
            "N"
        };
        #endregion

        #region Names
        private static readonly string[] NAMES =
        {
            "Pad extended",
            "Pad reduced",
            "Standard pad",
            "Laser",
            "Magnet",
            "Glue",
            "Pauser",
            "Standard ball",
            "Heavy ball",
            "Perforaball",
            "Clusterball",
            "Faster",
            "Slower",
            "Double",
            "Triple",
            "Quintuple",
            "Pad shield",
            "Pad shield",
            "Net",
            "Net",
        };
        #endregion

        public E_DropTypes Type
        {
            get;
            set;
        }

        public Color Color
        {
            get { return COLORS[(int)Type]; }
        }

        private static GeometricPrimitive m_Primitive = null;
        private Matrix m_WorldMatrix;

        public Drop() :
            base()
        {
            Type = E_DropTypes.Count_;      // Invalid
        }


        public Drop(E_DropTypes type) :
            base()
        {
            Type = type;
        }

        public override void Initialize()
        {
            base.Initialize();

            m_BoundingBox.Width = (int)SIZE.X;
            m_BoundingBox.Height = (int)SIZE.Y;

            IsActive = false;
        }

        private static readonly Vector2 SIZE = new Vector2(42, 24);

        protected override void LoadContent()
        {
            base.LoadContent();

            if (m_Primitive == null)
            {
                GraphicsDevice device = GameplayScreen.Instance.GraphicsDevice;
                m_Primitive = new RoundedCylinderPrimitive(device, SIZE.X, SIZE.Y, 8);
            }
        }

        public override void Update(float timeFactor)
        {
            m_Position.Y += timeFactor * 100;

            m_WorldMatrix = Matrix.CreateRotationZ(MathHelper.PiOver2) * Matrix.CreateTranslation(new Vector3(m_Position, -100.0f));

            m_BoundingBox.X = (int)(m_Position.X - (SIZE.X / 2.0f));
            m_BoundingBox.Y = (int)(m_Position.Y - (SIZE.Y / 2.0f));

            if (m_Position.Y > 720.0f)
                IsActive = false;
        }

        public override void Draw(float timeFactor)
        {
            GameplayScreen screen = GameplayScreen.Instance;

            int typeIndex = (int)Type;

            SceneInfo info = screen.SceneInfo;
            m_Primitive.Draw(m_WorldMatrix, info.ViewMatrix, info.ProjectionMatrix, Color);

            SpriteBatch spriteBatch = screen.SpriteBatch;
            SpriteFont font = screen.SpriteFontItems;
            Vector2 textSize = font.MeasureString(LETTERS[typeIndex]);
            Vector2 pos = Position - (textSize / 2.0f);
            spriteBatch.Begin();
            spriteBatch.DrawString(font, LETTERS[typeIndex], pos + Vector2.One, Color.Black);
            spriteBatch.DrawString(font, LETTERS[typeIndex], pos - Vector2.One, Color.Black);
            spriteBatch.DrawString(font, LETTERS[typeIndex], pos + new Vector2(1, -1), Color.Black);
            spriteBatch.DrawString(font, LETTERS[typeIndex], pos + new Vector2(-1, 1), Color.Black);
            spriteBatch.DrawString(font, LETTERS[typeIndex], pos, Color.White);
            spriteBatch.End();
        }

        public Rectangle GetBoundingBox()
        {
            return m_BoundingBox;
        }

        public override string ToString()
        {
            return NAMES[(int)Type];
        }
    }
}
